#include "server/CandidateResult.h"
#include "server/Dictionary.h"
#include "server/KeyRecommander.h"
#include "server/edit_distance.h"
#include "client/Configuration.h"

#include <unistd.h>
#include <iostream>

using std::cout;

string KeyRecommander::doQuery(const string &queWord){
    Dictionary *pdict = Dictionary::createInstance();
    const map<string, set<int>> &indexTable = pdict->getIndexTable(); // 词典索引

    set<int> indexId; // 获得的索引ID
    string index;
    for (size_t idx = 0; idx < queWord.length(); ++idx)
    {
        size_t nBytes = nBytesCode(queWord[idx]);
        index = queWord.substr(idx, nBytes);
        idx += (nBytes - 1);
        auto it = indexTable.find(index);
        if (it != indexTable.end())
        {
            indexId.insert(it->second.begin(), it->second.end());
        }
    }

    if (indexId.size() == 0)
    {
        return " ";
    }

    priority_queue<MyResult, vector<MyResult>, MyCompare> resultQue;
    statistic(queWord, indexId, resultQue);

    vector<string> result;

    cout << *((Configuration::getInstance(getcwd(NULL, 0))->find_config("candicateCount")).begin()) << '\n';
    const int candicateCount = 10;
    for (int i = 0; i < candicateCount; ++i)
    {
        if (!resultQue.empty())
        {
            cout << resultQue.top().getWord() << '\n';
            result.push_back(resultQue.top().getWord());
            resultQue.pop();
        }
    }

    string result_s;
    for(auto &i: result){
        result_s += i;
    }

    return result_s;
}

void KeyRecommander::execute() {}

void KeyRecommander::queryIndexTable() {}

void KeyRecommander::statistic(const string &queWord, set<int> &indexId, priority_queue<MyResult, vector<MyResult>, MyCompare> &resultQue) {
    Dictionary *pdict = Dictionary::createInstance();
    const vector<pair<string, int>> &dict = pdict->getDict(); // 词典

    for (auto it = indexId.begin(); it != indexId.end(); ++it)
    {
        MyResult result(dict[*it].first, dict[*it].second);
        int dist = distance(queWord, dict[*it].first);
        result.setDist(dist);
        resultQue.push(result);
    }
}

int KeyRecommander::distance(const string &lhs, const string &rhs) {
    return editDistance(lhs, rhs);
}